#pragma once

#include "Primitive/VertexGroup.h"
#include "Math/BoundingBox.h"

#include "Object/Object.h"

#include "Containers/Vector.h"

#include "StaticMesh.m.h"


class CRenderMesh;
class RMaterial;

RCLASS(ExtraHeader=["Material/Material.h"])
class WHENGINE_API RStaticMesh : public RObject
{
    ROBJECT
    RStaticMesh();
public:

    SVec3 GetHalfExtent()
    {
        return Boundary.GetHalfExtent();
    }

    bool HaveVertex()
    {
        return !VertexGroups.Empty();
    }

    float GetBoundingSphereRadius()
    {
        return BoundingSphere;
    }

    void SetBoundingBox(SBoundingBox InBoundingBox);

    SBoundingBox GetBoundingBox()
    {
        return Boundary;
    }

    void SetVertice(const TVector<SVertex>& InVertice
        ,const TVector<uint32_t>& InIndices
        ,bool UpdateBounding=true);

    void SetVertice(TVector<SVertexGroup> InVertexGroups, bool UpdateBounding=true);

    int32_t GetSectionNum();

    //index buffer might be empty
    static TSharedObjectPtr<RStaticMesh> CreateMesh(const TVector<SVertex>& InVertice,const TVector<uint32_t>& InIndices);

    static TSharedObjectPtr<RStaticMesh> CreateMesh(const TVector<SVertexGroup>& InVertexGroup);

    TVector<std::shared_ptr<CRenderMesh>> GetRenderMeshes();

    void PostLoadFromAsset() override;

    RFIELD()
    TVector<TSharedObjectPtr<RMaterial>> DefaultMaterials;
    
    void SyncToRenderThread();
protected:
    RFIELD()
    SBoundingBox Boundary; 
    
    RFIELD()
    float BoundingSphere = .0f;

    RFIELD()
    TVector<SVertexGroup> VertexGroups;

    friend class CGltfLoader;

    TVector<std::shared_ptr<CRenderMesh>> RenderMeshes;

};
